﻿using System;
using System.Collections.Generic;
using Wala.Connection.Objects.Timeline;
using Wala.Connection.HttpsConnections;
using System.Threading.Tasks;
using Wala.Infrastructure;
using Newtonsoft.Json.Linq;

namespace Wala.Connection.Managements
{
    public class TimelineManager
    {
        public const int FRIEND_MOMENT = 0;
        public const int MY_MOMENT = 1;
        public const int ALL_MOMENT = 2;

        #region //---------- Get Info for timeline -------------//

        /// <summary>
        ///     Get list of TimelineInfo for timeline include PhotoInfo and StatusInfo
        /// </summary>
        /// <param name="type">
        ///     0 = friend
        ///     1 = mine
        ///     2 = both
        /// </param>
        /// <param name="uid">
        ///     Id of friend
        /// </param>
        /// <param name="start">
        ///     Start index
        /// </param>
        /// <param name="end">
        ///     End index
        /// </param>
        /// <returns>
        ///     List of TimelineInfo object
        /// </returns>
        public async static Task<List<TimelineInfo>> GetTimeline(int type, uint uid, int start, int end)
        {           
            string url = URLConstant.TIMLINE_HOST;
            switch (type)
            {
                case FRIEND_MOMENT:
                    url += string.Format(URLConstant.FRIEND_MOMENT, uid.ToString(), start.ToString(), end.ToString());
                    break;
                case MY_MOMENT:
                    url += string.Format(URLConstant.MY_MOMENT, start.ToString(), end.ToString());
                    break;
                case ALL_MOMENT:
                    url += string.Format(URLConstant.ALL_MOMENT, start.ToString(), end.ToString());
                    break;
                default:
                    url += string.Format(URLConstant.MY_MOMENT, 0, 0);
                    break;
            }

            string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
            FeedData feed = FeedData.FromJson(result);
            List<TimelineInfo> lstTimelineInfo = new List<TimelineInfo>();
            foreach (FeedInfo feedInfo in feed.Feed)
            {
                if (feedInfo.Type == URLConstant.TargetType.PHOTO)
                {
                    PhotoInfo photo = PhotoInfo.FromJson(feedInfo.Data.ToString());
                    lstTimelineInfo.Add(photo);
                }
                if (feedInfo.Type == URLConstant.TargetType.STATUS)
                {
                    StatusInfo status = StatusInfo.FromJson(feedInfo.Data.ToString());
                    lstTimelineInfo.Add(status);
                }
            }
            return lstTimelineInfo;
        }

        /// <summary>
        /// Gets my timeline.
        /// </summary>
        /// <param name="start">The start.</param>
        /// <param name="end">The end.</param>
        /// <returns></returns>
        public async static Task<List<TimelineInfo>> GetMyTimeline(int start, int end)
        {
            return await GetTimeline(MY_MOMENT, 0, start, end);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public async static Task<List<TimelineInfo>> GetAllTimeline(int start, int end)
        {
            return await GetTimeline(ALL_MOMENT, 0, start, end);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public async static Task<List<TimelineInfo>> GetFriendTimeline(uint uid, int start, int end)
        {
            return await GetTimeline(FRIEND_MOMENT, uid, start, end);
        }

        /// <summary>
        /// Get a list of comments foreach feed as photo or status
        /// </summary>
        /// <param name="feedID"></param>
        /// <param name="type">type for photo or satus in target type</param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static async Task<List<Comment>> GetCommentListAsync(long feedID, int type, int start, int end)
        {            
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.GET_LIST_COMMENT, feedID.ToString(),
                                                                                                type.ToString(),
                                                                                                start.ToString(),
                                                                                                end.ToString());
            string json = await ClientHttpsRequest.HttpsRequest(url);
            CommentData commentData = CommentData.FromJson(json);
            return commentData.GetListComments();
        }

        /// <summary>
        /// Gets the photo comment list async.
        /// </summary>
        /// <param name="photoId">The photo id.</param>
        /// <param name="start">The start.</param>
        /// <param name="end">The end.</param>
        /// <returns></returns>
        public static async Task<List<Comment>> GetPhotoCommentListAsync(long photoId, int start, int end)
        {
            return await GetCommentListAsync(photoId, URLConstant.TargetType.PHOTO, start, end);
        }

        /// <summary>
        /// Gets the status comment list async.
        /// </summary>
        /// <param name="statusId">The status id.</param>
        /// <param name="start">The start.</param>
        /// <param name="end">The end.</param>
        /// <returns></returns>
        public static async Task<List<Comment>> GetStatusCommentListAsync(long statusId, int start, int end)
        {
            return await GetCommentListAsync(statusId, URLConstant.TargetType.STATUS, start, end);
        }

        /// <summary>
        /// Get list of users like
        /// </summary>
        /// <param name="feedID"></param>
        /// <param name="type">type for photo or satus in target type</param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static async Task<List<UserInfo>> GetUserLikeList(long feedID, int type, int start, int end)
        {            
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.GET_LIST_LIKE, feedID.ToString(),
                                                                                                type.ToString(),
                                                                                                start.ToString(),
                                                                                                end.ToString());
            string json = await ClientHttpsRequest.HttpsRequest(url);
            LikeData likeData = LikeData.FromJson(json);
            List<UserInfo> lstUserLike = likeData.LstUserInfo;
            return lstUserLike;
        }

        /// <summary>
        /// Get list of users tagged in an feed
        /// </summary>
        /// <param name="feedID"></param>
        /// <param name="type">type for photo or satus in target type</param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static async Task<List<UserInfo>> GetUserTagList(long feedID, int type, int start, int end)
        {            
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.GET_LIS_TAG_FEED, feedID.ToString(),
                                                                                                type.ToString(),
                                                                                                start.ToString(),
                                                                                                end.ToString());
            string json = await ClientHttpsRequest.HttpsRequest(url);
            TagData tagData = TagData.FromJson(json);
            List<UserInfo> lstUser = tagData.LstUserInfo;
            return lstUser;
        }

        /// <summary>
        /// Get Detail info for Photo Feed
        /// </summary>
        /// <param name="photoID"></param>
        /// <returns></returns>
        public static async Task<PhotoInfo> GetPhotoInfoDetail(long photoID)
        {           
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.VIEW_PHOTO_DETAIL, photoID.ToString());
            string json = await ClientHttpsRequest.HttpsRequestWithCookie(url);
            PhotoInfo photoInfo = PhotoInfo.FromJson(json);
            return photoInfo;
        }

        /// <summary>
        /// Get Detail info for Status Feed
        /// </summary>
        /// <param name="statusID"></param>
        /// <returns></returns>
        public static async Task<StatusInfo> GetStatusInfoDetail(long statusID)
        {            
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.VIEW_STATUS, statusID.ToString());
            string json = await ClientHttpsRequest.HttpsRequestWithCookie(url);
            StatusInfo statusInfo = StatusInfo.FromJson(json);
            return statusInfo;
        }

        /// <summary>
        /// Gets the timeline info detail async.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="type">The type.</param>
        /// <returns></returns>
        public static async Task<TimelineInfo> GetTimelineInfoDetailAsync(long id, int type)
        {
            switch (type)
            {
                case URLConstant.TargetType.STATUS:
                    return await TimelineManager.GetStatusInfoDetail(id);

                case URLConstant.TargetType.PHOTO:
                    return await TimelineManager.GetPhotoInfoDetail(id);

                default:
                    throw new ArgumentException("type");
            }
        }        

        #endregion


        #region //----------- Action for timeline --------------//

        /// <summary>
        /// Like an feed and return true if success or false if not
        /// </summary>
        /// <param name="targetID">ID of feed</param>
        /// <param name="targetType">type of feed</param>
        /// <param name="locationX"></param>
        /// <param name="locationY"></param>
        /// <returns></returns>
        public static async Task<bool> DoLike(long targetID, int targetType, string locationX, string locationY)
        {
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.LIKE, targetID.ToString(),
                                                                                    targetType.ToString(),
                                                                                    locationX,
                                                                                    locationY);
            try
            {
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                int code = (int)jObject["code"];
                if (code == Constants.Constants.TimeLineErrorCode.SUCCESS)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }

        }

        /// <summary>
        /// UnLike an feed and return true if success or false if not
        /// </summary>
        /// <param name="targetID">ID of feed</param>
        /// <param name="targetType">type of feed</param>
        /// <param name="locationX"></param>
        /// <param name="locationY"></param>
        /// <returns></returns>
        public static async Task<bool> DoUnLike(long targetID, int targetType, string locationX, string locationY)
        {
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.UNLIKE, targetID.ToString(),
                                                                                    targetType.ToString(),
                                                                                    locationX,
                                                                                    locationY);
            try
            {                
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                int code = (int)jObject["code"];
                if (code == Constants.Constants.TimeLineErrorCode.SUCCESS)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// Action for create comment for a feed
        /// </summary>
        /// <param name="text"></param>
        /// <param name="targetID">Id of an feed</param>
        /// <param name="targetType">type of feed in targetType</param>
        /// <param name="locationX"></param>
        /// <param name="locationY"></param>
        /// <returns></returns>
        public static async Task<long> CreateComment(string text, long targetID, int targetType, double locationX, double locationY)
        {
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.CREATE_COMMENT, text,
                                                                                    targetID.ToString(),
                                                                                    targetType.ToString(),
                                                                                    locationX,
                                                                                    locationY);
            long commentID = 0;

            try
            {                
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                commentID = (long)jObject["comment_id"];
            }
            catch (Exception ex)
            {

            }
            return commentID;
        }

        /// <summary>
        /// Action Delete a comment for an feed
        /// </summary>
        /// <param name="commentID"></param>
        /// <returns></returns>
        public static async Task<bool> DeleteComment(long commentID)
        {
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.DELETE_COMMENT, commentID.ToString());
            try
            {                
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                int code = (int)jObject["code"];
                if (code == Constants.Constants.TimeLineErrorCode.SUCCESS)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {

            }
            return false;
        }

        /// <summary>
        /// Action Multi Tag for a feed 
        /// </summary>
        /// <param name="targetID">Id of feed</param>
        /// <param name="targetType">type of feed in TargetType</param>
        /// <param name="recipients">List string of WalaID</param>
        /// <param name="locationX"></param>
        /// <param name="locationY"></param>
        /// <returns></returns>
        public static async Task<bool> DoMultiTag(long targetID, int targetType, List<string> recipients, string locationX, string locationY)
        {
            string lstRecipients = "";
            int index = 0;
            foreach (string recipient in recipients)
            {
                if (index == 0)
                    lstRecipients += recipient + "," + URLConstant.ReciptionType.User;
                else
                    lstRecipients += ";" + recipient + "," + URLConstant.ReciptionType.User;
                index++;
            }
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.MULTI_TAG, targetID.ToString(),
                                                                                targetType.ToString(),
                                                                                lstRecipients,
                                                                                locationX,
                                                                                locationY);
            try
            {                
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                int code = (int)jObject["code"];
                if (code == Constants.Constants.TimeLineErrorCode.SUCCESS)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {

            }
            return false;
        }

        /// <summary>
        /// Action Untag a user for a feed
        /// </summary>
        /// <param name="targetID">Id of a feed</param>
        /// <param name="targetType">type of a feed in targetFeed</param>
        /// <param name="recipientID"></param>
        /// <param name="recipientType"></param>
        /// <param name="locationX"></param>
        /// <param name="locationY"></param>
        /// <returns></returns>
        public static async Task<bool> RemoveTag(long targetID, int targetType, int recipientID, int recipientType, string locationX, string locationY)
        {
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.UN_TAG, targetID.ToString(),
                                                                                targetType.ToString(),
                                                                                recipientID.ToString(),
                                                                                recipientType.ToString(),
                                                                                locationX,
                                                                                locationY);

            try
            {                
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                int code = (int)jObject["code"];
                if (code == Constants.Constants.TimeLineErrorCode.SUCCESS)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {

            }
            return false;
        }

        /// <summary>
        /// Action Unfollow a feed
        /// </summary>
        /// <param name="feedId">Id of feed</param>
        /// <param name="targetType">type of feed in TargetType</param>
        /// <returns></returns>
        public static async Task<bool> DoUnfollow(long feedId, int targetType)
        {
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.UNFOLLOW, feedId.ToString(), targetType.ToString());
            try
            {                
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                int code = (int)jObject["code"];
                if (code == Constants.Constants.TimeLineErrorCode.SUCCESS)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {

            }
            return false;
        }

        /// <summary>
        /// Action Follow a feed
        /// </summary>
        /// <param name="feedId">Id of feed</param>
        /// <param name="targetType">type of feed in TargetType</param>
        /// <returns></returns>
        public static async Task<bool> DoFollow(long feedId, int targetType)
        {
            string url = URLConstant.TIMLINE_HOST + string.Format(URLConstant.FOLLOW, feedId.ToString(), targetType.ToString());
            try
            {                
                string result = await ClientHttpsRequest.HttpsRequestWithCookie(url);
                JObject jObject = JObject.Parse(result);
                int code = (int)jObject["code"];
                if (code == Constants.Constants.TimeLineErrorCode.SUCCESS)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {

            }
            return false;
        }
        
        #endregion
    }
}
